#ifndef _ECMFS_SSL_
#define _ECMFS_SSL_
#include <openssl/pem.h>
#include <openssl/x509.h>
#include "ecmfs_cmn.h"

#define RSA_KEYLEN 2048
#define AES_ROUNDS 6  

typedef enum ssl_ret_ {
    SSL_SUCCESS,
    SSL_ERROR
}ssl_ret_t;
#define KEY_PAIR_RSA_PRI 1
#define KEY_PAIR_RSA_PUB 2
#define KEY_SINGLE_RSA_PUB 3
#define KEY_SINGLE_RSA_PRIV 4
#define KEY_AES_KEY 5
#define KEY_AES_IV 6

typedef int (*PASS_CB_FPTR)(char *buf, int size, int rwflag, void *u);
typedef struct ssl_t_ {
    /* related to keys */
	char keyStorePath[100];
	char root_ca_cert[100];
	char my_cert[100];
	X509 *my_x509_cert;
	
	char my_enc_pub_key[100];
	char my_enc_priv_key[100];
	char my_enc_priv_key_password[100];
	EVP_PKEY *enc_key;
	EVP_PKEY *enc_pub_key;
	EVP_PKEY *enc_priv_key;
	
	char my_sign_pub_key[100];
	char my_sign_priv_key[100];
	char my_sign_priv_key_password[100];
	EVP_PKEY *sign_key;
	EVP_PKEY *sign_pub_key;
	EVP_PKEY *sign_priv_key;

	char root_sign_pub_key_name[100];
	char root_sign_priv_key_name[100];
	char root_sign_priv_key_password[100];
	EVP_PKEY *root_sign_key;
	EVP_PKEY *root_sign_pub_key;
	EVP_PKEY *root_sign_priv_key;

	char root_enc_pub_key_name[100];
	char root_enc_priv_key_name[100];
	char root_enc_priv_key_password[100];
	EVP_PKEY *root_enc_key;
	EVP_PKEY *root_enc_pub_key;
	EVP_PKEY *root_enc_priv_key;
	
    unsigned char *aesEncKey;
    unsigned char *aesEncIV;	
    unsigned char *aesSignKey;
    unsigned char *aesSignIV;	
	
	/* common for all keys */
    EVP_CIPHER_CTX *rsaEncryptCtx;
    EVP_CIPHER_CTX *rsaDecryptCtx;
    EVP_CIPHER_CTX *aesEncryptCtx;
    EVP_CIPHER_CTX *aesDecryptCtx;
	
} ssl_t;
extern ssl_t ecmfs_ssl;

/* OpenSSL Functions -------------------------------------------*/
void init_ssl(void);
void cleanup_openssl(void);
void handle_openssl_error(void);

/* Config Init Functions -------------------------- */
ssl_ret_t set_keyStore_path(ssl_t *this, char *keyStorePath);
ssl_ret_t set_root_ca_cert(ssl_t *this, char *root_ca_cert);

/* Symmetric Key Functions ------------------ */
ssl_ret_t ssl_init_aes_encrypt_decrypt_contexts(ssl_t *this);
ssl_ret_t ssl_deinit_aes_encrypt_decrypt_contexts(ssl_t *this);
ssl_ret_t ssl_gen_aes_keys(ssl_t *this, unsigned char **aesKey, 
    unsigned char **aesIV);
int writeAESKeyToFile(FILE *fd, int key, void *key1, void *key2);

/* Asymmetric RSA Public Key/Private Key Functions ----------  */

ssl_ret_t ssl_init_rsa_encrypt_decrypt_contexts(ssl_t *this);
ssl_ret_t ssl_deinit_rsa_encrypt_decrypt_contexts(ssl_t *this);
ssl_ret_t ssl_gen_rsa_keys(ssl_t *this, EVP_PKEY **keypair);
ssl_ret_t writeRSAKeyToFile(FILE *fd, int key, void *key1, 
                      char *pass);
ssl_ret_t ssl_write_rsa_keys_to_file(ssl_t *this, 
                char *my_pub_key, char *my_priv_key, 
                char *my_priv_key_password,
                EVP_PKEY *pkey);
ssl_ret_t ssl_write_rsa_keys_to_file(ssl_t *this, 
                char *my_pub_key, char *my_priv_key, 
                char *my_priv_key_password,
                EVP_PKEY *pkey);
ssl_ret_t create_my_encryption_keys(ssl_t *this, char *my_enc_pub_key,
             char *my_enc_priv_key, char *my_enc_priv_key_password);
ssl_ret_t create_my_signing_keys(ssl_t *this, char *my_sign_pub_key,
             char *my_sign_priv_key, char *my_sign_priv_key_password);
ssl_ret_t read_rsa_key_pair(ssl_t *this, 
            char *pub_key_fname,
            char *priv_key_fname,
            char *password,EVP_PKEY **pPrivKey,
            EVP_PKEY **pPubKey);
ssl_ret_t read_my_encryption_keys(ssl_t *this, char *my_enc_pub_key,
             char *my_enc_priv_key, char *my_enc_priv_key_password);
ssl_ret_t read_my_signing_keys(ssl_t *this, char *my_sign_pub_key,
             char *my_sign_priv_key, char *my_sign_priv_key_password);


ssl_ret_t create_root_signing_keys(ssl_t *this, char *my_sign_pub_key,
             char *my_sign_priv_key, char *my_sign_priv_key_password);
ssl_ret_t create_root_encryption_keys(ssl_t *this, char *my_enc_pub_key,
             char *my_enc_priv_key, char *my_enc_priv_key_password);


ssl_ret_t read_root_encryption_keys(ssl_t *this, char *my_enc_pub_key,
             char *my_enc_priv_key, char *my_enc_priv_key_password);
ssl_ret_t read_root_signing_keys(ssl_t *this, char *my_sign_pub_key,
             char *my_sign_priv_key, char *my_sign_priv_key_password);
ssl_ret_t read_rsa_pub_key(ssl_t *this, 
            char *pub_key_fname,
            EVP_PKEY **pPubKey);
/* Encode/Decode Functions -------------------------- START */
ssl_ret_t decode_rsa_message(ssl_t *this,EVP_PKEY *key,
                    unsigned char *buffer, int bufsize, 
                    unsigned char **decode_buffer, int *decode_bufsize);
ssl_ret_t encode_rsa_message(ssl_t *this,EVP_PKEY *key,
                    unsigned char *buffer, int bufsize, 
                    unsigned char **encode_buffer, int *encode_bufsize);
ssl_ret_t decode_aes_message(ssl_t *this,unsigned char *aesKey,
                    unsigned char *aesIV,
                    unsigned char *buffer, int bufsize, 
                    unsigned char **decode_buffer, int *decode_bufsize);
ssl_ret_t encode_aes_message(ssl_t *this,unsigned char *aesKey, 
                    unsigned char *aesIV, 
                    unsigned char *buffer, int bufsize, 
                    unsigned char **encode_buffer, int *encode_bufsize);
EVP_PKEY *generate_key(ssl_t *this);
X509 *generate_x509(ssl_t *this, EVP_PKEY * pkey);
ssl_ret_t create_key_pair(ssl_t *this, char *my_pub_key,
              char *my_priv_key, char *my_priv_key_password,
	      EVP_PKEY **pkey);
/* Certificate Functions -------------------------- START*/
X509 * generate_x509(ssl_t *this, EVP_PKEY * pkey);
ssl_ret_t create_my_cert(ssl_t *this, char *my_cert);
ssl_ret_t destroy_my_cert(ssl_t *this);




#endif
